﻿using Microsoft.Phone.Tasks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Media;
using Windows8Accelerator.Core.Xaml.Converters;
using Windows8Accelerator.Core.Xaml.Helpers;
using Windows8Accelerator.Core.Xaml.Html;

namespace Windows8Accelerator.Core.Xaml.Controls.RichText
{
    public class RichTextFactory : RichTextFactoryBase
    {
        public override object NewLineBreak()
        {
            return new LineBreak();
        }

        public override void AddToParent(object Parent, object result, SuperHtmlNodeVisitor visitor)
        {
            if (Parent is RichTextBox && result is Inline)
            {
                var richTextBlock = ((RichTextBox)Parent);
                var placeHolder = richTextBlock.Blocks.FirstOrDefault((b) => b.Name.Equals("RichTextHtmlSourcePlaceHolder")) as Paragraph;
                if (placeHolder == null)
                    placeHolder = GetRichTextHtmlSourcePlaceHolder(richTextBlock);
                if (placeHolder != null)
                {
                    //placeHolder.LineStackingStrategy = LineStackingStrategy.MaxHeight;
                    placeHolder.Inlines.Add(result as Inline);
                    RedefineParents(placeHolder, visitor);
                    return;
                }
                var paragraph = new Paragraph();
                SetRichTextHtmlSourcePlaceHolder(richTextBlock, paragraph);
                //paragraph.LineStackingStrategy = LineStackingStrategy.MaxHeight;
                paragraph.Inlines.Add(result as Inline);
                richTextBlock.Blocks.Add(paragraph as Block);
                RedefineParents(paragraph, visitor);
            }
            else if (Parent is RichTextBox && result is Block)
            {
                ((RichTextBox)Parent).Blocks.Add(result as Block);
            }
            else if (Parent is Paragraph && result is Inline)
            {
                ((Paragraph)Parent).Inlines.Add(result as Inline);
            }
            else if (Parent is Span && result is Inline)
            {
                ((Span)Parent).Inlines.Add(result as Inline);
            }
        }

        private void RedefineParents(object parent, SuperHtmlNodeVisitor visitor)
        {
            while (visitor != null && visitor.Parent is RichTextBox)
            {
                visitor.Parent = parent;
                visitor = visitor.ParentVisitor;
            }
        }

        public override object NewRun(string text, SuperTextFormat textFormat)
        {
            var run = new Run() { Text = text };
            SuperTextFormatHelper.FormatTextElement(textFormat, run);
            return run;
        }

        public override object NewImage(string imageSrc, double? width, double? height)
        {
            var viewBox = new Viewbox();
            viewBox.Stretch = Stretch.Uniform;
            viewBox.StretchDirection = StretchDirection.DownOnly;

            var image = new Image();
            viewBox.Child = image;
            var stringToImageConverter = new StringToImageConverter();
            image.Source = stringToImageConverter.Convert(imageSrc, typeof(ImageSource), null, null) as ImageSource;
            if (width.HasValue && height.HasValue)
            {
                viewBox.Stretch = Stretch.Uniform;
                viewBox.StretchDirection = StretchDirection.Both;
                viewBox.Width = width.Value;
                viewBox.Height = height.Value;

                //image.Stretch = Stretch.Uniform;
                //image.Width = width.Value;
                //image.Height = height.Value;
            }
            else if (width.HasValue)
            {
                viewBox.Stretch = Stretch.Uniform;
                viewBox.StretchDirection = StretchDirection.Both;
                viewBox.Width = width.Value;
                //image.Stretch = Stretch.Uniform;
                //image.Width = width.Value;
            }
            else if (height.HasValue)
            {
                viewBox.Stretch = Stretch.Uniform;
                viewBox.StretchDirection = StretchDirection.Both;
                viewBox.Height = height.Value;
                //image.Stretch = Stretch.Uniform;
                //image.Height = height.Value;
            }
            else
            {
            }

            var inlineUIContainer = new InlineUIContainer();

            //if (!htmlNode.Ancestors("a").Any())
            //{
            //    var hyperlinkButton = new HyperlinkButton();
            //    var resourceDictionary = new ResourceDictionary();
            //    resourceDictionary.Source = new Uri("ms-appx:///Windows8Accelerator.Core.Xaml/Themes/Generic.xaml");
            //    hyperlinkButton.Style = resourceDictionary["RichTextHyperlinkButtonStyle"] as Style;
            //    hyperlinkButton.Content = viewBox;
            //    inlineUIContainer.Child = hyperlinkButton;

            //    SetHref(hyperlinkButton, imageSrc);

            //    hyperlinkButton.Click += (s, e) =>
            //    {
            //        var href = GetHref((ButtonBase)s);
            //        var args = new ImageClickEventArgs() { Src = href };
            //        OnImageClick(args);
            //    };
            //}
            //else
            {
                inlineUIContainer.Child = viewBox;
            }

            return inlineUIContainer;
        }

        public override object NewListItem(int? orderCount, int indentLevel, out object newParent, SuperTextFormat textFormat)
        {
            var grid = new Grid();
            grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(indentLevel * 40) });
            grid.ColumnDefinitions.Add(new ColumnDefinition());

            var richTextBlock0 = new RichTextBox();
            richTextBlock0.Padding = new Thickness();
            richTextBlock0.Margin = new Thickness();
            SuperTextFormatHelper.FormatControl(textFormat, richTextBlock0);

            var markerParagraph = new Paragraph()
            {
                TextAlignment = TextAlignment.Right,
            };
            var marker = "•";
            if (orderCount.HasValue)
            {
                marker = string.Format("  {0})", orderCount);
            }
            markerParagraph.Inlines.Add(new Run() { Text = marker });
            richTextBlock0.Blocks.Add(markerParagraph);

            grid.Children.Add(richTextBlock0);

            var richTextBlock1 = new RichTextBox();
            richTextBlock1.Padding = new Thickness();
            richTextBlock1.Margin = new Thickness();
            SuperTextFormatHelper.FormatControl(textFormat, richTextBlock1);
            grid.Children.Add(richTextBlock1);
            Grid.SetColumn(richTextBlock1, 1);

            newParent = richTextBlock1;

            var inlineUIContainer = new InlineUIContainer();
            inlineUIContainer.Child = grid;
            return inlineUIContainer;
        }

        public override object NewUnderline()
        {
            return new Underline();
        }

        public override object NewA(string href, out object newParent, SuperTextFormat textFormat, Action<HyperlinkClickEventArgs> onHyperlinkClick)
        {
            var inlineUIContainer = new InlineUIContainer();

            var hyperlinkButton = new HyperlinkButton();
            var resourceDictionary = new ResourceDictionary();
            resourceDictionary.Source = new Uri("/Windows8Accelerator.Core.Xaml;component/Themes/Generic.xaml", UriKind.Relative);
            hyperlinkButton.Style = resourceDictionary["RichTextHyperlinkButtonStyle"] as Style;
            SuperTextFormatHelper.FormatControl(textFormat, hyperlinkButton);
            hyperlinkButton.Margin = new Thickness(0, 0, 0, -4);
            //var handCursor = new CoreCursor(CoreCursorType.Hand, 1);
            //hyperlinkButton.PointerEntered += (s, e) =>
            //{
            //    ((FrameworkElement)(s)).Tag = Window.Current.CoreWindow.PointerCursor;
            //    Window.Current.CoreWindow.PointerCursor = handCursor;
            //    e.Handled = true;
            //};
            //hyperlinkButton.PointerMoved += (s, e) =>
            //{
            //    Window.Current.CoreWindow.PointerCursor = handCursor;
            //    e.Handled = true;
            //};
            //PointerEventHandler pointerLost = (s, e) =>
            //{
            //    Window.Current.CoreWindow.PointerCursor = ((FrameworkElement)(s)).Tag as CoreCursor;
            //    e.Handled = true;

            //};
            //hyperlinkButton.PointerExited += pointerLost;
            //hyperlinkButton.PointerCanceled += pointerLost;
            //hyperlinkButton.PointerCaptureLost += pointerLost;

            SetHref(hyperlinkButton, href);

            hyperlinkButton.Click += (s, e) =>
            {
                var href1 = GetHref((ButtonBase)s);
                var args = new HyperlinkClickEventArgs() { Href = href1 };
                onHyperlinkClick(args);
                if (!args.Handled && Uri.IsWellFormedUriString(href, UriKind.Absolute))
                {
                    var wbt = new WebBrowserTask();
                    wbt.Uri = new Uri(href, UriKind.Absolute);
                    wbt.Show();
                }
            };

            inlineUIContainer.Child = hyperlinkButton;

            var richTextBlock1 = new RichTextBox();
            richTextBlock1.Padding = new Thickness();
            richTextBlock1.Margin = new Thickness();
            SuperTextFormatHelper.FormatControl(textFormat, richTextBlock1);
            hyperlinkButton.Content = richTextBlock1;

            newParent = richTextBlock1;

            return inlineUIContainer;
        }

        public static string GetHref(ButtonBase button)
        {
            return (string)button.GetValue(HrefProperty);
        }

        public static void SetHref(ButtonBase button, string value)
        {
            button.SetValue(HrefProperty, value);
        }

        public static readonly DependencyProperty HrefProperty =
            DependencyProperty.Register("Href", typeof(string), typeof(ButtonBase), new PropertyMetadata(""));

        public static Paragraph GetRichTextHtmlSourcePlaceHolder(RichTextBox richTextBlock)
        {
            return (Paragraph)richTextBlock.GetValue(RichTextHtmlSourcePlaceHolderProperty);
        }

        public static void SetRichTextHtmlSourcePlaceHolder(RichTextBox richTextBlock, Paragraph value)
        {
            richTextBlock.SetValue(RichTextHtmlSourcePlaceHolderProperty, value);
        }

        public static readonly DependencyProperty RichTextHtmlSourcePlaceHolderProperty =
            DependencyProperty.Register("RichTextHtmlSourcePlaceHolder", typeof(Paragraph), typeof(RichTextBox), new PropertyMetadata(null));

        public static void ClearPrevious(RichTextBox richTextBlock)
        {
            var placeHolder = richTextBlock.Blocks.FirstOrDefault((b) => b.Name.Equals("RichTextHtmlSourcePlaceHolder")) as Paragraph;
            if (placeHolder == null)
                placeHolder = GetRichTextHtmlSourcePlaceHolder(richTextBlock);
            if (placeHolder != null)
            {
                placeHolder.Inlines.Clear();
            }
        }
    }
}
